{
 "metadata": {
  "name": ""
 },
 "nbformat": 3,
 "nbformat_minor": 0,
 "worksheets": [
  {
   "cells": [
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "\"\"\"\n",
      " Copyright (C) 2011, Enthought Inc\n",
      " Copyright (C) 2011, Patrick Henaff\n",
      "\n",
      " This program is distributed in the hope that it will be useful, but WITHOUT\n",
      " ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS\n",
      " FOR A PARTICULAR PURPOSE.  See the license for more details.\n",
      "\"\"\"\n",
      "from __future__ import print_function\n",
      "from quantlib.instruments.api import AmericanExercise, VanillaOption, Put\n",
      "from quantlib.instruments.payoffs import PlainVanillaPayoff\n",
      "from quantlib.pricingengines.api import BaroneAdesiWhaleyApproximationEngine, FDAmericanEngine\n",
      "from quantlib.processes.black_scholes_process import BlackScholesMertonProcess\n",
      "from quantlib.quotes import SimpleQuote\n",
      "from quantlib.settings import Settings\n",
      "from quantlib.time.api import Actual365Fixed, Date, May, TARGET\n",
      "from quantlib.termstructures.volatility.equityfx.black_vol_term_structure \\\n",
      "        import BlackConstantVol\n",
      "from quantlib.termstructures.yields.api import FlatForward\n",
      "\n",
      "def main():\n",
      "    # global data\n",
      "    todays_date = Date(15, May, 1998)\n",
      "    Settings.instance().evaluation_date = todays_date\n",
      "    settlement_date = Date(17, May ,1998)\n",
      "\n",
      "    risk_free_rate = FlatForward(\n",
      "        reference_date = settlement_date,\n",
      "        forward        = 0.06,\n",
      "        daycounter     = Actual365Fixed()\n",
      "    )\n",
      "\n",
      "    # option parameters\n",
      "    exercise = AmericanExercise(\n",
      "        earliest_exercise_date = settlement_date,\n",
      "        latest_exercise_date   = Date(17, May, 1999)\n",
      "    )\n",
      "    payoff = PlainVanillaPayoff(Put, 40.0)\n",
      "\n",
      "    # market data\n",
      "    underlying = SimpleQuote(36.0)\n",
      "    volatility = BlackConstantVol(todays_date, TARGET(), 0.20, Actual365Fixed())\n",
      "    dividend_yield = FlatForward(\n",
      "        reference_date = settlement_date,\n",
      "        forward        = 0.00,\n",
      "        daycounter     = Actual365Fixed()\n",
      "    )\n",
      "\n",
      "    # report\n",
      "    header = '%19s' % 'method' + ' |' + \\\n",
      "            ' |'.join(['%17s' % tag for tag in ['value',\n",
      "                                                'estimated error',\n",
      "                                                'actual error' ] ])\n",
      "    print()\n",
      "    print(header)\n",
      "    print('-'*len(header))\n",
      "\n",
      "    refValue = None\n",
      "    def report(method, x, dx = None):\n",
      "        e = '%.4f' % abs(x-refValue)\n",
      "        x = '%.5f' % x\n",
      "        if dx:\n",
      "            dx = '%.4f' % dx\n",
      "        else:\n",
      "            dx = 'n/a'\n",
      "        print('%19s' % method + ' |' + \\\n",
      "            ' |'.join([('%17s' % y) for y in [x, dx, e] ]))\n",
      "\n",
      "    # good to go\n",
      "\n",
      "    process = BlackScholesMertonProcess(\n",
      "        underlying, dividend_yield, risk_free_rate, volatility\n",
      "    )\n",
      "\n",
      "    option = VanillaOption(payoff, exercise)\n",
      "\n",
      "    refValue = 4.48667344\n",
      "    report('reference value',refValue)\n",
      "\n",
      "    # method: analytic\n",
      "\n",
      "    option.set_pricing_engine(BaroneAdesiWhaleyApproximationEngine(process))\n",
      "    report('Barone-Adesi-Whaley',option.net_present_value)\n",
      "\n",
      "    return\n",
      "\n",
      "    option.setPricingEngine(BjerksundStenslandEngine(process))\n",
      "    report('Bjerksund-Stensland',option.net_present_value)\n",
      "\n",
      "    # method: finite differences\n",
      "    timeSteps = 801\n",
      "    gridPoints = 800\n",
      "\n",
      "    option.setPricingEngine(FDAmericanEngine(process,timeSteps,gridPoints))\n",
      "    report('finite differences',option.net_present_value)\n",
      "\n",
      "    # method: binomial\n",
      "    timeSteps = 801\n",
      "\n",
      "    option.setPricingEngine(BinomialVanillaEngine(process,'jr',timeSteps))\n",
      "    report('binomial (JR)',option.net_present_value)\n",
      "\n",
      "    option.setPricingEngine(BinomialVanillaEngine(process,'crr',timeSteps))\n",
      "    report('binomial (CRR)',option.NPV())\n",
      "\n",
      "    option.setPricingEngine(BinomialVanillaEngine(process,'eqp',timeSteps))\n",
      "    report('binomial (EQP)',option.NPV())\n",
      "\n",
      "    option.setPricingEngine(BinomialVanillaEngine(process,'trigeorgis',timeSteps))\n",
      "    report('bin. (Trigeorgis)',option.NPV())\n",
      "\n",
      "    option.setPricingEngine(BinomialVanillaEngine(process,'tian',timeSteps))\n",
      "    report('binomial (Tian)',option.NPV())\n",
      "\n",
      "    option.setPricingEngine(BinomialVanillaEngine(process,'lr',timeSteps))\n",
      "    report('binomial (LR)',option.NPV())\n",
      "\n",
      "if __name__ == '__main__':\n",
      "    main()"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "output_type": "stream",
       "stream": "stdout",
       "text": [
        "\n",
        "             method |            value |  estimated error |     actual error\n",
        "----------------------------------------------------------------------------\n",
        "    reference value |          4.48667 |              n/a |           0.0000\n",
        "Barone-Adesi-Whaley |          4.46563 |              n/a |           0.0210\n"
       ]
      }
     ],
     "prompt_number": 2
    }
   ],
   "metadata": {}
  }
 ]
}